<?php
namespace wow\model;

/**
 * Wrapper around soap iface.
 * 
 * @author peec
 *
 */
class Soap{
	
	/**
	 * The client connection.
	 * @var \SoapClient
	 */
	private $client;
	
	
	private $user = null;
	
	private $soapPermissions = array();
	
	/**
	 * Generates a new soap connection for specific realm id.
	 * @param int $realmId Realm id.
	 * @return wow\model\Soap
	 */
	static public function generateSoapFactory($realmId, $user = null){
		$r = \gnomephp\Configuration::get('worlddbs', $realmId);
		
		if (isset($r['soap']) && $r['soap']['enable_soap']){
			
			return new Soap(
			strtoupper($r['soap']['admin_user']), 
			strtoupper($r['soap']['admin_password']),
			$r['soap']['host'],
			$r['soap']['port'],
			$user,
			$r['soap']['permissions']
			);
		}
		return null;
	}
	
	/**
	 * Checks permissions against custom config array.
	 * @param string $name Method name ( function name )
	 * @throws \Exception Throws exception on permission error.
	 */
	private function checkPermission($name){
		$access = true;

		if ($this->user && $this->soapPermissions){
			$access = false;
			$config = $this->soapPermissions[$name];
			$level = $this->user->getGmLevel();
			if ($level){
				if (is_array($config) && in_array($level, $config)){
					$access = true;
				}elseif($level >= $config){
					$access = true;
				}
			}
		}
		if (!$access){
			throw new \Exception("No access in permission list");
		}
	}
	
	
	public function __construct($username, $password, $host='127.0.0.1', $port=7878, $user = null, $soapPermissions = null){
		$this->client = new \SoapClient(null,
			array(
				'location' => "http://$host:$port/",
				'uri' => "urn:MaNGOS",
				'style' => SOAP_RPC,
				'login' => $username,
				'password' => $password
			)
			
		);
		$this->user = $user;
		$this->soapPermissions = $soapPermissions;
		

	}
	
	
	public function sendMail($name, $subject, $message){
		$this->checkPermission(__FUNCTION__);
		return $this->com('send mail '.$name.' '.$this->quote($subject).' '.$this->quote($message));
	}
	public function sendMoney($name, $subject, $message, $gold){
		$this->checkPermission(__FUNCTION__);
		return $this->com('send money '.$name.' '.$this->quote($subject).' '.$this->quote($message) . ' ' . $gold);
	}
	public function sendItems($name, $subject, $message, $items){
		$this->checkPermission(__FUNCTION__);
		$i = '';
		foreach($items as $itemId => $amount){
			$i .= $itemId . '[:'.$amount.'] ';
		}
		
		return $this->com('send items '.$name.' '.$this->quote($subject).' '.$this->quote($message) . ' ' . $i);
	}
	
	public function announce($message){
		$this->checkPermission(__FUNCTION__);
		return $this->com('announce '.$message);
	}
	
	public function gmAnnounce($message){
		$this->checkPermission(__FUNCTION__);
		return $this->com('gmannounce '.$message);
	}
	public function notify($message){
		$this->checkPermission(__FUNCTION__);
		return $this->com('notify '.$message);
	}
	
	public function mute($name, $timeInMinutes, $reason){
		$this->checkPermission(__FUNCTION__);
		return $this->com("mute {$name} {$timeInMinutes} {$this->quote($reason)}");
	}
	public function unMute($name){
		$this->checkPermission(__FUNCTION__);
		return $this->com("unmute {$name}");
	}
	public function revive($name){
		$this->checkPermission(__FUNCTION__);
		return $this->com("revive {$name}");
	}
	
	public function kick($name){
		$this->checkPermission(__FUNCTION__);
		return $this->com("kick {$name}");
	}
	
	public function hello(){
		$this->checkPermission(__FUNCTION__);
		return $this->com("hello");
	}
	
	
	
	private function quote($str){
		return '"'.str_replace('"', '\"', $str).'"';
	}
	
	
	/**
	 * Tries to run command against the soap server.
	 * @param string $command The server command to run.
	 */
	protected function com($command){
		return $this->client->executeCommand(new \SoapParam((string)$command, "command"));
	}
	
	
	
}